import time
import requests
from rest_framework import serializers
from utils.centent.cos import create_bucket
from django_redis import get_redis_connection

from api import models
from django.conf import settings
from utils.common.check import check_phone


class LoginRegisterModelSerializer(serializers.ModelSerializer):
    """
    登录注册序列化器
    """
    """
{
    "phone": "19803630852",
    "username": "梦",
    "avatar": "https://thirdwx.qlogo.cn/mmopen/vi_32/DYAIOgq83er91ib1lzkI4jEB9VkdZCX
    nnSE82xelsQg1McVkybwbcqxL6jGJWM7kKeNNpd5iaCDTcd4CS6gN7jtw/132",
    "code": "2528"
}

    """

    code = serializers.CharField(max_length=4, write_only=True)
    openid = serializers.CharField(write_only=True)

    # code = serializers.SerializerMethodField()

    class Meta:
        model = models.UserInfo
        fields = ['username', 'phone', 'avatar', 'code', 'openid']

    def validate(self, attrs):
        phone, h_code, username, avatar, openid = self._get_data(attrs)
        # 手机号校验
        ret = self._check_phone(phone)
        if not ret:
            raise serializers.ValidationError('手机号格式错误')
        # 校验code
        self._check_code(phone=phone, h_code=h_code)
        # 检查openid
        self._check_openid(openid)
        # 以phone进行查询，后面的default是没有创建的
        # get_...两个参数，用户对象，bool(存在返回False，新创建的返回True)
        # print(openid)
        try:
            user_obj, boole = models.UserInfo.objects.get_or_create(phone=phone,
                                                                    defaults={'username': username, 'avatar': avatar,
                                                                              'openid': openid})
        except:
            raise serializers.ValidationError('存在')
        if boole:
            # 新创建的用户---注册
            self._create_bucket(user_obj=user_obj, phone=phone)
        # 获取token
        token = self._get_token(user=user_obj)
        # 返回信息
        self._give_data(user_obj=user_obj, token=token)
        # 真正的openid
        rel_openid = self._get_openid(wx_code=openid)
        user_obj.openid = rel_openid
        # 对openid进行更新
        user_obj.wx_openid = openid
        user_obj.save()
        return attrs

    def _get_data(self, attrs):
        """获取数据"""
        phone = attrs.get('phone')
        h_code = attrs.get('code')
        username = attrs.get('username')
        avatar = attrs.get('avatar')
        openid = attrs.get('openid')
        return phone, h_code, username, avatar, openid

    def _check_phone(self, phone):
        """手机号校验"""
        ret = check_phone(phone)
        return ret

    def _check_code(self, h_code, phone):
        if not h_code:
            raise serializers.ValidationError('验证码不能为空')
        conn = get_redis_connection('sms_code')
        r_code = conn.get('sms_code_%s' % phone)
        if not r_code:
            raise serializers.ValidationError('验证码过期')
        if r_code.decode('utf-8') != h_code:
            raise serializers.ValidationError('验证码错误')

    def _check_openid(self, openid):
        """校验openid"""
        if not openid:
            raise serializers.ValidationError('不合法登录')

    def _give_data(self, user_obj, token):
        """
        在context赋值，用于返回前端
        """
        self.context['user_id'] = user_obj.id
        self.context['username'] = user_obj.username
        self.context['phone'] = user_obj.phone
        self.context['avatar'] = user_obj.avatar
        self.context['bucket'] = user_obj.bucket
        self.context['region'] = user_obj.region
        self.context['balance'] = user_obj.balance
        self.context['fans'] = user_obj.fans
        self.context['follow'] = user_obj.follow
        self.context['token'] = token

    def _get_token(self, user):
        from rest_framework_jwt.settings import api_settings
        # 生成token
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)
        return token

    def _create_bucket(self, user_obj, phone):
        # 新建一个桶，将信息赋值给当前的user_obj
        Bucket = '{}-{}-1305448189'.format(phone, str(int(time.time())))
        create_bucket(Bucket=Bucket)
        user_obj.bucket = Bucket
        user_obj.save()

    def _get_openid(self, wx_code):
        """发送请求获取真正的openid"""
        # openid的获取：需要拿着wx_code去微信申请
        #  https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html
        # login服务端，发送请求的路由地址
        # https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html
        info = {
            'appid': settings.WX_APPID,  # 微信小程序appid
            'secret': settings.WX_SECRET,  # 微信小程序密钥key
            'js_code': wx_code,  # openid
            'grant_type': "authorization_code",  # 默认值即可
        }
        result = requests.get(url='https://api.weixin.qq.com/sns/jscode2session', params=info)
        rel_openid = result.json()['openid']
        return rel_openid
